package net.ufrog.common.redis.serializers;

import com.alibaba.fastjson.JSON;
import net.ufrog.common.Logger;
import net.ufrog.common.exception.ServiceException;

import java.nio.charset.Charset;

/**
 * @author ultrafrog, ufrog.net@gmail.com
 * @version 0.1, 2016-09-27
 * @since 0.1
 */
public class FastJsonSerializer implements Serializer {

    @Override
    public byte[] serialize(Object object) {
        String value = JSON.toJSONString(new JsonObject(object));
        Logger.debug("serialize to: %s", value);
        return value.getBytes(Charset.forName("utf-8"));
    }

    @Override
    public Object deserialize(byte[] bytes) {
        try {
            String value = new String(bytes, Charset.forName("utf-8"));
            Logger.debug("deserialize from: %s", value);
            JsonObject jsonObject = JSON.parseObject(value, JsonObject.class);
            return JSON.parseObject(jsonObject.getValue(), Class.forName(jsonObject.getType()));
        } catch (ClassNotFoundException e) {
            throw new ServiceException(e.getMessage(), e);
        }
    }

    /**
     * @author ultrafrog, ufrog.net@gmail.com
     * @version 0.1, 2016-09-27
     * @since 0.1
     */
    private class JsonObject {

        /** 类型 */
        private String type;

        /** 内容 */
        private String value;

        /** 构造函数 */
        JsonObject() {}

        /**
         * 构造函数
         *
         * @param object 内容
         */
        JsonObject(Object object) {
            this();
            value = JSON.toJSONString(object);
            type = object.getClass().getName();
        }

        /**
         * 读取类型
         *
         * @return 类型
         */
        public String getType() {
            return type;
        }

        /**
         * 设置类型
         *
         * @param type 类型
         */
        public void setType(String type) {
            this.type = type;
        }

        /**
         * 读取内容
         *
         * @return 内容
         */
        public String getValue() {
            return value;
        }

        /**
         * 设置内容
         *
         * @param value 内容
         */
        public void setValue(String value) {
            this.value = value;
        }
    }
}
